package edu.columbia.gate.plugins;

import gate.Annotation;
import gate.DocumentContent;
import gate.FeatureMap;
import gate.SimpleAnnotation;
import gate.corpora.DocumentContentImpl;
import gate.util.InvalidOffsetException;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

public abstract class DocumentUtils
{

	public static void deleteAllAnnotations(gate.Document document)
	{
		document.getAnnotations().clear();

		// get the names of all sets
		Map namedSets = document.getNamedAnnotationSets();
		// nothing left to do if there are no named sets
		if (namedSets == null || namedSets.isEmpty())
			return;

		// loop through the sets and delete them all unless they're original
		// markups
		List setNames = new ArrayList(namedSets.keySet());
		Iterator iter = setNames.iterator();
		String setName;

		while (iter.hasNext())
		{
			setName = (String) iter.next();
			// check first whether this is the original markups or one of the
			// sets
			// that we want to keep
			if (setName != null)
			{
				// skip named sets from setsToKeep
				document.removeAnnotationSet(setName);
			}// if
		}
	}

	public static void replaceDocumentContent(gate.Document document,
			String newContent)
	{
		DocumentContent newDocContent = new DocumentContentImpl(newContent);
		if(document == null)
		{
			return;
		}
		else if (document.getContent() == null)
		{
			document.setContent(newDocContent);
		}
		else
		{
			try
			{
				document.edit((long) 0, document.getContent().size() - 1,
						newDocContent);
			} catch (InvalidOffsetException e)
			{
				e.printStackTrace();
			}
		}
	}
	
	public static Map.Entry<String, Integer> getMaximumValuedEntry(java.util.Map<String, Integer> map)
	{
		if(map == null || map.entrySet() == null) return null;
		Set<Map.Entry<String, Integer>> set = (Set<Map.Entry<String, Integer>>) map.entrySet();
		Map.Entry<String, Integer> maxEntry = null;
		Integer maxValue = Integer.MIN_VALUE;
		for (Entry<String, Integer> entry : set)
		{
			if(entry.getValue() != null && entry.getValue() > maxValue)
			{
				maxEntry = entry;
				maxValue = maxEntry.getValue();
			}
		}
		return maxEntry;
	}
	
	public static String joinArray(Object[] arr, String separator)
	{
		if(arr == null || arr.length <= 0) return "";
		if(separator == null) separator = ",";
		
		String str = "";
		if(arr[0] != null)
			str = arr[0].toString();
		for(int i=1; i<arr.length; i++)
		{
			if(arr[i] != null)
				str += separator + arr[i];
		}
		return str;
	}
	
	//created by Zhi
	//in the features area in GATE, puts the number of times a structure is mentioned next to the structure number
	public static String joinHashTable(Map m, String separator)
	{
		if(m == null || m.size() == 0) return "";
		if(separator == null) separator = ",";
		
		String str = "";
		Iterator iter = m.entrySet().iterator();
		while(iter.hasNext())
		{
			Map.Entry pairs = (Map.Entry)iter.next();
			str += "|" + pairs.getKey() + "=" + pairs.getValue();
		}
		str = str.substring(1);
		return str;
	}
	
	public static Object getFeatureValue(gate.Document doc, String featureName)
	{
		FeatureMap features = doc.getFeatures();
		return features.get(featureName);		
	}

	public static void setFeatureValue(gate.Document doc, String featureName, Object value)
	{
		FeatureMap features = doc.getFeatures();
		features.put(featureName, value);		
	}
	
	public static void increaseFeatureValue(gate.Document doc, String featureName)
	{
		addFeatureValue(doc, featureName, 1);		
	}
	
	public static void decreaseFeatureValue(gate.Document doc, String featureName)
	{
		addFeatureValue(doc, featureName, -1);
	}

	public static void addFeatureValue(gate.Document doc, String featureName, int value)
	{
		FeatureMap features = doc.getFeatures();
		if(! features.containsKey(featureName))
			features.put(featureName, 0);
		Integer oldValue = (Integer) features.get(featureName);
		features.put(featureName, oldValue.intValue() + value );
	}
}
